﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ATM
{
    /// <summary>
    /// Database class, to maintain accounts.
    /// </summary>
    class Database
    {
        int Balance;        //< the amount of money the account has
        string AccountNumber;       //<the account's ID
        string PINCode;     //< the account's PIN code

        /// <summary>
        /// This function validates the PIN code of the particular bank account
        /// </summary>
        /// <param name="InputPin">Typed PIN</param>
        /// <returns>True if PIN code was correct, false otherwise</returns>
        public bool CheckPIN(string InputPin)
        {
            if (String.Compare(InputPin, this.PINCode) == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// This function returns the account ID (unused for now)
        /// </summary>
        /// <returns>The account ID</returns>
        public string getAccountID()
        {
            return this.AccountNumber;
        }

        /// <summary>
        /// This function returns the balance of the account
        /// </summary>
        /// <returns>Amount of money it has</returns>
        public int getBalance()
        {
            return this.Balance;
        }

        /// <summary>
        /// This function takes an amount of cash on the account
        /// It does not check if the account has enough money
        /// maybe it should be done on this level
        /// </summary>
        /// <param name="Amount">The amount of money it takes</param>
        public void TakeCash(int Amount)
        {
            this.Balance -= Amount;
        }
        /// <summary>
        /// This function changes the PIN code if the old PIN was valid.
        /// </summary>
        /// <param name="oldPIN">The old PIN code</param>
        /// <param name="newPIN">The new PIN code</param>
        /// <returns>True, if PIN changed, false if not.</returns>
        public bool ChangePIN(string oldPIN, string newPIN)
        {
            if (String.Compare(oldPIN, this.PINCode) == 0)
            {
                this.PINCode = newPIN;
                return true;
            }
            else
            {
                return false;
            }
            
        }

        /// <summary>
        /// Creates a new account with a random cash reserve.
        /// </summary>
        /// <param name="InputAccount">The ID of the new account</param>
        public Database(string InputAccount)
        {
            this.AccountNumber = InputAccount;
            this.Balance = RandNumGen.Next(1, 100) * 1000;
            this.PINCode = InputAccount.Substring(12);
        }

        /// <summary>
        /// Creates a new account with an inputted cash reserve.
        /// </summary>
        /// <param name="InputAccount">The ID of the new account</param>
        /// <param name="InputBalance">The balance of the new account</param>
        /// <param name="InputPIN">The PIN code of the new account</param>
        public Database(string InputAccount, string InputBalance, string InputPIN)
        {
            this.AccountNumber = InputAccount;
            this.Balance = Convert.ToInt32(InputBalance);
            this.PINCode = InputPIN;
        }
        
        public static List<Database> ListAccounts = new List<Database>(); //<list of available accounts
        static Random RandNumGen = new Random(); //<randomgenerator for the starting amount of cash to the accounts

        /// <summary>
        /// Static construtor for loading an earlier database.
        /// 
        /// Databases are Blowfish-encrypted.
        /// </summary>
        static Database()
        {
            String InputDatabase = Crypter.decrypt();

            try
            {
                string[] HashedString = InputDatabase.Split(';');
                for (int i = 0; i < HashedString.Length - 1; i++)
                {
                    string[] AccountData = HashedString[i].Split(',');
                    ListAccounts.Add(new Database(AccountData[0], AccountData[1], AccountData[2]));
                }

            }
            catch
            {
            }

        }
        /// <summary>
        /// This function saves the database.
        /// </summary>
        public static void Logout(){

            string SavedDatabase = "";

            for (int i = 0; i < ListAccounts.Count; i++)
            {
                SavedDatabase += ListAccounts[i].ToFile();
            }

            Crypter.encrypt(SavedDatabase);
        }

        /// <summary>
        /// This subfunction creates a string for the saving routine
        /// </summary>
        /// <returns>An entry of an account</returns>
        private string ToFile()
        {
            return AccountNumber + "," + Balance + "," + PINCode + ";";
        }
    }

}
